/*
* 类  : 通过函数  通过class(es6)
* 实例 : 通过new 类得到的
* 原型 : 类.原型 `实例.__proto__ === 类.prototype`
* 原型链 : 实例-->类的原型-->类的原型的隐式原型-->类的原型的隐式原型的隐式原型  `man.__proto__.__proto__.__proto__.__proto__`
* 构造函数 : 指针指向的是类本身  es5中通过 类.prototype.constructor  es6把类和构造完全分开了
* 成员方法成员属性  : 直接挂载到类里面的this上面的 所有的实例都可以调用
* 实例方法实例属性 :  挂载在实例上  当前实例能调用
* 原型方法原型属性 :  挂载到类的原型上
* 静态方法和静态属性 : 挂载到类上面的
*
* 继承
* 多态
* 封装
* 抽象
*
* 成员方法和原型方法有什么区别  成员方法挂载到了每一个实例上  原型方法挂载到类的原型上
* 原型和原型链什么关系
* 原型方法 和 实例方法 什么区别
* 构造函数和类什么关系
* 实现继承有几种方式
* 怎么理解多态
* 继承后实例有什么变化
* new 了之后 会有什么变化
* */


// 怎么创建一个类
// 函数创建 首字母大写
function Person(name) {
  // 属性或者方法
  // 成员方法和成员属性
  this.name = name;
  this.sayName = function () {
    return this.name;
  };
}

// 原型方法和原型属性
Person.prototype.age = 20;
Person.prototype.sayAge = function () {
  return this.age;
};


// 通过类的实例调用成员方法和成员属性
const person = new Person('小张');
console.log(person.name);
console.log(person.sayName());

console.log(person.age);


const person1 = new Person('小李');

// true / false  地址
console.log(person1.sayName === person.sayName); // false new多少次 创建多少次
console.log(person1.sayAge === person.sayAge); //  true 创建一个空间


person1.sayName.x = 20;
person1.sayAge.y = 30;

console.log(person.sayName.x);//undefined
console.log(person.sayAge.y); //30

// 实例属性和实例方法
person.sayNickName = function (nickName) {
  return nickName
};

// 调用
console.log(person.sayNickName('张三疯子'));
// console.log(person1.sayNickName('张二疯子')); 此实例中没有上一个实例的方法

// es6 创建的类

class Person1 {
  constructor() {
    this.name = '小李';
  }

  // 静态方法
  // static name = this.name;
  static sayAge(age) {
    console.log(this); // this指向的是类本身
    return age
  }

  say(age) {
    console.log(this);
    return age
  }
}

const person2 = new Person1();
// console.log(Person1.sayAge(30));
console.log(Person1.name,'Person1.name');
// console.log(person2.say(20));


class Man extends Person{

}

const man = new Man();

man.toString();
